﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using UCL.Powersource.ViewModels;
using System.Reflection;
using PowersourceUIToolkit;
using UCL.Powersource.TFS;
using System.IO;

namespace UCL.Powersource
{
    public class PowersourceBootStrapper : PowersourceBootstrapperBase
    {
        

        protected override bool ValidateAssembly(string assemblyFilename)
        {
            #if DEBUG
            if (assemblyFilename == "SimoneUILibrary.dll") return true;
            #endif
            FileInfo fi = new FileInfo(assemblyFilename);
            if (!fi.Exists) return false;
            var r = Assembly.ReflectionOnlyLoadFrom(fi.FullName);
            var token = r.GetName().GetPublicKeyToken();
            var psAss = Assembly.GetExecutingAssembly();
            var psAssToken = psAss.GetName().GetPublicKeyToken();

            if (token == null || token.Length == 0) return false;

            for (int i = 0; i < psAssToken.Length; i++)
            {
                if (token.Length < i) return false;
                if (token[i] != psAssToken[i]) return false;
            }
            
            //// {253,102,229, 164,  82,105 ,251, 31}
            //We are passing all assemblies with valid strong name based on the powersource 1 here
            return true;
        }

        public PowersourceBootStrapper()
        {

            Log = LogManager.GetLog(typeof(Bootstrapper));
            #if DEBUG
            var tmp = Path.Combine(Path.GetTempPath(), string.Format( "PowersourceRun{0:yyyyMMdd}.log",DateTime.Now));
            LogManager.DefaultInstance.AddLog(new FileLog(VerbosityLevels.Debug,tmp,false));
            #endif
            Log.Trace("In powersourceBootStrapper constructor");
            ExtensibilityFiles.Add("SimoneUILibrary.dll");
            ExtensibilityFiles.Add("NobukoAnalyzer.dll");
        }
        protected override void Configure()
        {
          

            Log.Trace("[{0}] : Configure", this);
            
            EnvDTE.IVsExtensibility extensibility = PowersourcePackage.GetGlobalService(typeof(EnvDTE.IVsExtensibility)) as EnvDTE.IVsExtensibility;
            Log.Trace(" EnvDTE.IVsExtensibility = {0}", extensibility);
            IVsEnv = new VSEnv((EnvDTE80.DTE2)extensibility.GetGlobalsObject(null).DTE);
            Log.Trace(" IVsEnv = {0}", IVsEnv);
            TfsTeamProjectCollectionFactory = new TfsTeamProjectCollectionFactoryAdapter();
            PackageConfigurationFactory = new PackageConfigurationFactory();
            
            DefaultInterfaceImplementationTypes.Add(typeof(IAnalysisBridge), typeof(AnalysisBridge));
            StatisticManager = new StatisticManager();
            ReportingManager = new ReportingManager();
            UIManager = new UIManager();
            IPowersourceExt = new PowersourceExt();
            StatisticManagerQueue = new StatisticManagerQueue();
            RemoteBuilderQueue = new RemoteBuilderQueue();
            TypesToLoad = new Type[] { typeof(PowersourceMainViewModel) };
            base.Configure();
        }

        //IPowersourceExt IPowersourceExt;

        //protected override void InitializeIoCDependants()
        //{
        //    Debug.WriteLine("[{0}] : Initializing extensibility - Start", this);
        //    try
        //    {
        //        PowersourceConnector.Configure(IPowersourceExt);
        //        IPowersourceExt.ReportingManager.Initialize();
        //        IPowersourceExt.StatisticManager.Initialize();
        //    }
        //    catch (Exception Exception)
        //    {
        //        if (IPowersourceExt.Log != null)
        //            IPowersourceExt.Log.Error(Exception, "Initialize composable parts thrown an exception. Bootstrapper cannot be build. ");
        //        throw;
        //    }
        //    Debug.WriteLine("[{0}] : Initializing extensibility - Done", this);
        //}

        //protected override object GetInstance(Type serviceType, string key)
        //{
        //    Debug.WriteLine("[{0}] : GetInstance {1} key {2} ", this,serviceType.Name,key);
        //    string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
        //    var exports = container.GetExportedValues<object>(contract);

        //    if (exports.Count() > 0)
        //        return exports.First();

        //    throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
        //}

        //protected override IEnumerable<object> GetAllInstances(Type serviceType)
        //{
        //    return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        //}

        //protected override void BuildUp(object instance)
        //{
        //    container.SatisfyImportsOnce(instance);
        //}

        //protected override void OnDisposing()
        //{
        //    ViewModelLocator.DisposeViewModels(true);
        //    ViewLocator.DisposeViews(true);

        //    if (container != null)
        //    {
        //        container.Dispose();
        //        container = null;
        //    }
        //    base.OnDisposing();
        //}

        
        

        /// <summary>
        /// Current only load Powersource assemblyFile 
        /// </summary>
        /// <returns>A list of assemblies to inspect.</returns>
        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            var list = new List<Assembly>(base.SelectAssemblies());
            var gea = Assembly.GetExecutingAssembly();
            list.Add(gea);
            var sharedEA = typeof(Bootstrapper).Assembly;
            list.Add(sharedEA);

            return list.Distinct();
            
        }


        //TO DELETE 
        //public static PowersourceBootStrapper AttachCurrentApplication(ResourceDictionary rd)
        //{
        //    PowersourceBootStrapper pbs;



        //    if (rd != null)
        //    {
        //        pbs = ((PowersourceBootStrapper)rd[KEY_Bootstrapper]);
        //    }
        //    else
        //    {
        //        rd = new ResourceDictionary();
        //        pbs = new PowersourceBootStrapper();
        //        rd[KEY_Bootstrapper] = pbs;
        //    }
        //    Debug.Assert(pbs != null);
        //    pbs.Application = Application.Current;
        //    if (rd != null) pbs.Application.Resources.MergedDictionaries.Add(rd);
        //    pbs.PrepareApplication();

        //    //pbs.OnStartup(Application.Current, new StartupEventArgs() );
        //    return pbs;
        //}

      

     
    }
}
